//----BEGIN LICENSE----//
/*****************************************************************\
** prevalentLite - sqlite3 persistence object library 
**
** Copyright (C) 2008 Philip R. Schuchardt
**
** This program is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation, either version 3 of the License, or
** (at your option) any later version.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program.  If not, see <http://www.gnu.org/licenses/>.
**
*****************************************************************/
//----END LICENSE----//

/*!
\class plFactory plFactory.h <plFactory>

\brief Can dynamically create new objects by their classname.

If subclasses are setup correctly, see plObject for detials, the classes are automaticlly added to plFactory.

Example:
\code

plFactory factory;

//Make a new MyObj
MyObj* obj = (MyObj*)factory->New("MyObj");

\endcode

 */

#include "plFactory.h"

//Static map for the lookup
std::map<std::string, plFactoryElement*> plFactory::Lookup;

//!Constructor
plFactory::plFactory() {
    PopulateMap();
} //end plFactory

////////////////////////////////////////////////
/*!
  \brief Creats a new object based on the className

    If this function returns NULL then you didn't setup your subclass of plObject correctly.  You probably forgot use the pl_DECLARE_CLASS and pl_DEFINE_CLASS(classname).
  */
////////////////////////////////////////////////
plObject* plFactory::New(const char* className) {
    std::map<std::string, plFactoryElement*>::iterator iter;
    iter =  Lookup.find(className);
    if(iter != Lookup.end()) {
        plFactoryElement* element = (*iter).second;
        plObject* object = (element->NewFunctionPtr)();
        return object;
    }
    return NULL;
}

//Populates the Lookup map
void plFactory::PopulateMap() {

    plFactoryElement* current = plFactoryElement::Head;

    //While we still can go through all the registered objects
    while(current != NULL) {
        Lookup[current->GetClassName()] = current;
        current = current->Next;
    }

} //end PopulateMap


